package com.chinawlx.wlxteacher.ui.activity;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
import android.hardware.Camera;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;

import com.chinawlx.wlxteacher.R;
import com.chinawlx.wlxteacher.utils.WLXActivityManagerUtil;
import com.chinawlx.wlxteacher.utils.WLXConstant;
import com.chinawlx.wlxteacher.utils.WLXFileUtil;
import com.chinawlx.wlxteacher.utils.WLXLogUtil;
import com.chinawlx.wlxteacher.widget.WLXCustomToast;
import com.chinawlx.wlxteacher.widget.video_record.WLXVideoRecordProgressView;
import com.yixia.camera.MediaRecorderBase;
import com.yixia.camera.MediaRecorderSystem;
import com.yixia.camera.VCamera;
import com.yixia.camera.model.MediaObject;

import java.io.File;
import java.util.ArrayList;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

/**
 * 作者:吴名
 * 时间:16/8/26
 * 描述:交作业页面(录制视频以及拍照)
 */
public class WLXRecordVideoPhotoActivity extends WLXBaseActivity implements MediaRecorderBase
        .OnErrorListener, MediaRecorderBase.OnVideoAppendListener, MediaRecorderBase
        .OnTakePictureListener {


    @BindView(R.id.cb_switchCamera)
    CheckBox mCbSwitchCamera;
    @BindView(R.id.cb_switchFlashlight)
    CheckBox mCbSwitchFlashlight;
    @BindView(R.id.surfaceView_preview)
    SurfaceView mSurfaceViewPreview;
    @BindView(R.id.tv_pressToRecord)
    TextView mTvPressToRecord;
    @BindView(R.id.progress_record)
    WLXVideoRecordProgressView mProgressRecord;
    @BindView(R.id.iv_dot)
    ImageView mIvDot;
    @BindView(R.id.tv_center)
    TextView mTvCenter;
    @BindView(R.id.tv_right)
    TextView mTvRight;
    @BindView(R.id.tv_press)
    TextView mTvPress;
    @BindView(R.id.ctv_delete)
    CheckedTextView mCtvDelete;
    @BindView(R.id.iv_ok)
    ImageView mIvOk;
    @BindView(R.id.tv_left)
    TextView mTvLeft;

    private Context mContext;
    /**
     * 目前是否处于视频录制状态
     */
    private boolean isVideo = true;

    /**
     * SDK视频录制对象
     */
    private MediaRecorderBase mMediaRecorder;
    /**
     * 视频信息
     */
    private MediaObject mMediaObject;
    /**
     * 录制最长时间
     */
    public final static int RECORD_TIME_MAX = 45 * 1000;
    /**
     * 录制最小时间
     */
    public final static int RECORD_TIME_MIN = 3 * 1000;
    /**
     * 刷新进度条
     */
    private static final int HANDLE_INVALIDATE_PROGRESS = 0;
    /**
     * on
     */
    private boolean mCreated;

    /**
     * 是否是点击状态
     */
    private volatile boolean mPressedStatus;
    /**
     * 是否已经释放
     */
    private volatile boolean mReleased;
    /**
     * 需要重新编译（拍摄新的或者回删）
     */
    private boolean mRebuild;


    // TODO: 16/8/30 还有防止内存泄露的操作待完成 
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case HANDLE_INVALIDATE_PROGRESS:
                    if (mMediaRecorder != null && !isFinishing()) {
                        if (mProgressRecord != null) mProgressRecord.invalidate();
                        if (mPressedStatus) sendEmptyMessageDelayed(0, 30);
                    }
                    break;
            }
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        mCreated = false;
        super.onCreate(savedInstanceState);
        WLXActivityManagerUtil.addActivity(this);
        mContext = this;
        setContentView(R.layout.activity_hand_homework);
        ButterKnife.bind(this);

        initVideoRecord();
        initViews();
        mCreated = true;
    }

    /**
     * 加载视图
     */
    private void initViews() {
        //绑定监听事件
        //14以上,SurfaceView可以监听触摸
        mSurfaceViewPreview.setOnTouchListener(mOnSurfaveViewTouchListener);

        mTvPress.setOnTouchListener(mOnVideoControllerTouchListener);

        mProgressRecord.setMaxDuration(RECORD_TIME_MAX);
    }


    /**
     * 手动对焦
     */
    private View.OnTouchListener mOnSurfaveViewTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (mMediaRecorder == null || !mCreated) {
                return false;
            }
            switch (motionEvent.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    //检测是否手动对焦
                    if (checkCameraFocus(motionEvent)) {
                        return true;
                    }
                    break;
            }
            return true;
        }
    };


    /**
     * 点击屏幕录制
     */
    private View.OnTouchListener mOnVideoControllerTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            if (mMediaRecorder == null || !isVideo) {
                return false;
            }
            switch (motionEvent.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    // 判断是否已经超时
                    if (mMediaObject.getDuration() >= RECORD_TIME_MAX) {
                        WLXCustomToast.show("录制视频已到达时间上限");
                        return true;
                    }
                    // 取消回删
                    if (cancelDelete()) {
                        return true;
                    }
                    startRecord();
                    break;
                case MotionEvent.ACTION_UP:
                    //暂停
                    if (mPressedStatus) {
                        stopRecord();
                    }
                    break;
            }
            return true;
        }
    };

    /**
     * 停止录制
     */
    private void stopRecord() {
        WLXLogUtil.printE("视频录制停止");
        mPressedStatus = false;
        mCbSwitchCamera.setEnabled(true);
        mCbSwitchFlashlight.setEnabled(true);
        if (mMediaRecorder != null) {
            mMediaRecorder.stopRecord();
        }
        mCbSwitchCamera.setVisibility(View.VISIBLE);
        mCbSwitchFlashlight.setVisibility(View.VISIBLE);
//        checkVideoDuration();
    }

    /**
     * 检测录制时间
     */
    private int checkVideoDuration() {
        int duration = 0;
        if (!isFinishing() && mMediaObject != null) {
            duration = mMediaObject.getDuration();
            if (duration == 0) {
                mCtvDelete.setVisibility(View.GONE);
                mIvOk.setVisibility(View.GONE);

                //只有将视频删除完了之后才会重新显示,可以切换拍照和视频
                mTvCenter.setVisibility(View.VISIBLE);
                mTvRight.setVisibility(View.VISIBLE);
                mIvDot.setVisibility(View.VISIBLE);
            } else {
                mCtvDelete.setVisibility(View.VISIBLE);
            }
        }
        return duration;
    }

    /**
     * 开始录制
     */
    private void startRecord() {
        WLXLogUtil.printE("视频录制开始");

        //隐藏视频,拍照按钮
        mTvCenter.setVisibility(View.INVISIBLE);
        mTvRight.setVisibility(View.INVISIBLE);
        mIvDot.setVisibility(View.INVISIBLE);

        if (mMediaRecorder != null) {
            MediaObject.MediaPart part = mMediaRecorder.startRecord();
            if (part == null) {
                return;
            }
            // 如果使用MediaRecorderSystem，不能在中途切换前后摄像头，否则有问题
            if (mMediaRecorder instanceof MediaRecorderSystem) {
                mCbSwitchCamera.setVisibility(View.INVISIBLE);
                mCbSwitchFlashlight.setVisibility(View.INVISIBLE);
            }
            mProgressRecord.setData(mMediaObject);
        }
        mRebuild = true;
        mPressedStatus = true;
        if (mHandler != null) {
            mHandler.removeMessages(HANDLE_INVALIDATE_PROGRESS);
            mHandler.sendEmptyMessage(HANDLE_INVALIDATE_PROGRESS);
        }
        mCtvDelete.setVisibility(View.VISIBLE);
        mIvOk.setVisibility(View.VISIBLE);
        mCbSwitchCamera.setEnabled(false);
        mCbSwitchFlashlight.setEnabled(false);
    }

    /**
     * 取消回删
     */
    private boolean cancelDelete() {
        if (mMediaObject != null) {
            MediaObject.MediaPart part = mMediaObject.getCurrentPart();
            if (part != null && part.remove) {
                part.remove = false;
                mCtvDelete.setChecked(false);

                if (mProgressRecord != null) {
                    mProgressRecord.invalidate();
                }
                return true;
            }
        }
        return false;
    }

    public void backMain(View view) {
        onBackPressed();
    }

    @Override
    public void onBackPressed() {
        if (mCtvDelete != null && mCtvDelete.isChecked()) {
            cancelDelete();
            return;
        }

        if (mMediaObject != null) {
            mMediaObject.delete();
        }
        finish();
    }

    /**
     * 初始化视频录制配置
     */
    private void initVideoRecord() {
        //1,设置拍摄视频缓存路径
        WLXLogUtil.printE("缓存路径" + WLXConstant.ExternalCacheDir);
        VCamera.setVideoCachePath(WLXConstant.ExternalCacheDir);
        //2,开启log输出,ffmpeg输出到logcat
        VCamera.setDebugMode(true);
        //3,初始化拍摄sdk
        VCamera.initialize(mContext);
        //4,防止锁屏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

    @OnClick({R.id.cb_switchCamera, R.id.cb_switchFlashlight, R.id.tv_right, R.id.ctv_delete, R
            .id.iv_ok, R.id.tv_left, R.id.tv_press})
    public void onClick(View view) {
        switch (view.getId()) {
            //切花摄像头
            case R.id.cb_switchCamera:
                //切换摄像头前关闭闪光灯
                if (mMediaRecorder != null) {
                    mMediaRecorder.switchCamera();
                    if (mCbSwitchFlashlight.isChecked()) {//闪光灯开着,现在关掉
                        mMediaRecorder.toggleFlashMode();
                        mCbSwitchFlashlight.setChecked(false);
                    }
                    mCbSwitchFlashlight.setEnabled(!mMediaRecorder.isFrontCamera());
                }
                break;
            //切换闪光灯
            case R.id.cb_switchFlashlight:
                if (mMediaRecorder != null && !mMediaRecorder.isFrontCamera()) {//非前置摄像头
                    WLXLogUtil.printE("切换闪光灯");
                    mMediaRecorder.toggleFlashMode();
                } else {
                    WLXCustomToast.show("使用前置摄像头无需打开闪光灯");
                }
                break;
            case R.id.tv_right:
                //==================拍照模式=================
                isVideo = false;
                //拍照标红
                mTvLeft.setVisibility(View.VISIBLE);
                mTvCenter.setText("拍照");
                mTvRight.setVisibility(View.GONE);

                mTvPress.setBackgroundResource(R.drawable.holddownthevideoshoot);
                mTvPress.setText("");
                mCtvDelete.setBackgroundResource(R.drawable.homeworkalbum);
                mCtvDelete.setVisibility(View.VISIBLE);
                mProgressRecord.setVisibility(View.INVISIBLE);
                break;

            case R.id.tv_left:
                //=====================录制视频模式===============
                isVideo = true;
                //视频标红
                mTvLeft.setVisibility(View.GONE);
                mTvCenter.setText("视频");
                mTvRight.setVisibility(View.VISIBLE);

                mTvPress.setBackgroundResource(R.drawable.homeworkholdtheracket);
                mTvPress.setText("按住拍");
                mCtvDelete.setBackgroundResource(R.drawable.trashhomework);
                mCtvDelete.setVisibility(View.GONE);
                mProgressRecord.setVisibility(View.VISIBLE);
                break;
            case R.id.ctv_delete:
                if (isVideo) {
                    //视频状态下,回删视频片段
                    if (mMediaObject != null) {
                        MediaObject.MediaPart part = mMediaObject.getCurrentPart();
                        if (part != null) {
                            if (part.remove) {
                                mRebuild = true;
                                part.remove = false;
                                mMediaObject.removePart(part, true);
                                mCtvDelete.setChecked(false);
                            } else {
                                part.remove = true;
                                mCtvDelete.setChecked(true);
                            }
                        }
                        if (mProgressRecord != null) {
                            mProgressRecord.invalidate();
                        }
                        //检测按钮状态
                        checkVideoDuration();
                    }
                } else {
                    Intent intent = new Intent(mContext, WLXSendPictureActivity.class);
                    intent.putExtra("from", WLXRecordVideoPhotoActivity.class.getSimpleName());
                    mContext.startActivity(intent);
                    finish();
                }
                break;
            case R.id.iv_ok:
                //停止录制,开始合并视频
                if (checkVideoDuration() >= RECORD_TIME_MIN) {
                    mMediaRecorder.startAppendVideo();
                } else {
                    WLXCustomToast.show("拍摄时间太短");
                }
                break;
            case R.id.tv_press:
                if (!isVideo) {
                    //================拍照,进入预览,滤镜界面=============
                    mMediaRecorder.takePicture();
                }

                break;
        }
    }

    /**
     * 手动对焦
     */
    @SuppressLint("NewApi")
    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    private boolean checkCameraFocus(MotionEvent event) {
        float x = event.getX();
        float y = event.getY();
        float touchMajor = event.getTouchMajor();
        float touchMinor = event.getTouchMinor();

        Rect touchRect = new Rect((int) (x - touchMajor / 2), (int) (y - touchMinor / 2), (int)
                (x + touchMajor / 2), (int) (y + touchMinor / 2));
        if (touchRect.right > 1000) touchRect.right = 1000;
        if (touchRect.bottom > 1000) touchRect.bottom = 1000;
        if (touchRect.left < 0) touchRect.left = 0;
        if (touchRect.right < 0) touchRect.right = 0;

        if (touchRect.left >= touchRect.right || touchRect.top >= touchRect.bottom) return false;

        ArrayList<Camera.Area> focusAreas = new ArrayList<>();
        focusAreas.add(new Camera.Area(touchRect, 1000));
        if (!mMediaRecorder.manualFocus(new Camera.AutoFocusCallback() {

            @Override
            public void onAutoFocus(boolean success, Camera camera) {
            }
        }, focusAreas)) {
        }
        return true;
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mMediaRecorder == null) {
            initMediaRecorder();
        } else {
            mCbSwitchFlashlight.setChecked(false);
            mMediaRecorder.prepare();
            mProgressRecord.setData(mMediaObject);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopRecord();
        if (!mReleased && mMediaRecorder != null) {
            mMediaRecorder.release();
            mReleased = true;
        } else {
            mReleased = false;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        mHandler.removeMessages(HANDLE_INVALIDATE_PROGRESS);
        mHandler = null;
    }

    /**
     * 初始化拍摄SDK
     */
    private void initMediaRecorder() {
        mMediaRecorder = new MediaRecorderSystem();
        mRebuild = true;

        mMediaRecorder.setOnErrorListener(this);//错误监听
        mMediaRecorder.setOnVideoAppendListener(this);//视频合并监听
        mMediaRecorder.setOnTakePictureListener(this);//拍照监听

        File f = new File(VCamera.getVideoCachePath());
        if (!WLXFileUtil.checkFile(f)) {
            f.mkdirs();
        }
        String key = String.valueOf(System.currentTimeMillis());
        mMediaObject = mMediaRecorder.setOutputDirectory(key, VCamera.getVideoCachePath() + "/" +
                key);
        mMediaRecorder.setSurfaceHolder(mSurfaceViewPreview.getHolder());
        mMediaRecorder.prepare();
    }


    @Override
    public void onVideoError(int what, int extra) {

    }

    @Override
    public void onAudioError(int what, String message) {

    }

    @Override
    public void onVideoAppendStart() {
        WLXLogUtil.printE("合并视频开始");
    }

    /**
     * 合并完成
     */
    @Override
    public void onVideoAppendComplete() {
        mRebuild = false;
        WLXLogUtil.printE("合并视频完成");
        String s = mMediaObject.getOutputDirectory();
        WLXLogUtil.printE(WLXFileUtil.getListFiles(s).toString());
        if (WLXFileUtil.getListFiles(s).size() == 1) {
            WLXConstant.VIDEO_PATH = WLXFileUtil.getListFiles(s).get(0).getAbsolutePath();
            WLXConstant.VIDEO_DURATION = mMediaObject.getDuration() + "";
            WLXLogUtil.printE("合成视频的路径:" + WLXConstant.VIDEO_PATH);
            startActivity(new Intent(mContext, WLXSendVideoActivity.class));
            WLXRecordVideoPhotoActivity.this.finish();
        }
    }

    /**
     * 视频合并错误
     */
    @Override
    public void onVideoAppendError() {
        WLXLogUtil.printE("合并视频error");
    }

    @Override
    public void onTakePictureComplete(final String picturePath) {
        WLXLogUtil.printE("拍照完图片绝对路径:" + picturePath);
        //这个的作用是让系统去扫描刚拍下的这个图片文件，以利于在MediaSore中能及时更新，
        // 可能会存在部分手机不用使用的情况（众所周知，现在国内的Rom厂商已把原生Rom改的面目全非）
        //mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse
        // ("file://" + mPictureSavePath)));
        MediaScannerConnection.scanFile(mContext, new String[]{picturePath}, null, new
                MediaScannerConnection.OnScanCompletedListener() {
            public void onScanCompleted(String path, Uri uri) {
                WLXLogUtil.printE("扫描完成:" + path);
                final Intent intent = new Intent(mContext, WLXFilterActivity.class);
                intent.putExtra(WLXConstant.IMAGE_PATH, picturePath);
                intent.putExtra("from", WLXRecordVideoPhotoActivity.class.getSimpleName());
                startActivity(intent);
                finish();
            }
        });
    }

    @Override
    public void onTakePictureError() {
        WLXCustomToast.show("拍照出现异常,请重试");
    }
}
